import java.io.*;

public class Scanner {
	
	private FileReader fileReader;
	private LineNumberReader inFile; 
	
	private int curColumn;
	private int curLine;
	
	
	//TSMAPI:RegisterSlashCommand("movedata",  TSM.SetLogFlag, L["Displays realtime move data."], true)
	private char T = 84;
	private char S = 83;
	private char M = 77;
	private char A = 65;
	private char P = 80;
	private char I = 73;
	private char openingParen = 40;
	
	private char legalMin = 32;
	private char legalMax = 126;
	
	private char dash = 45;
	private char openBracket = 91;
	private char closeBracket = 93;
	
	private char accept = 0;
	
	public Scanner(String filePath){

		
		try {
            //System.out.println(filePath);   //testing only
            fileReader = new FileReader(filePath);        //Establish file reader
            inFile = new LineNumberReader(fileReader);    //Establish scanner on file
            inFile.setLineNumber(1);                    //Sets line numbers to 1 base
            curLine = inFile.getLineNumber();           //Set line number
        } catch (FileNotFoundException e) {
            System.out.println(e);
            System.err.println("Compile failed, Quiting");
            System.exit(1);
        }
		curColumn = 0;
	  
	}//end constructor
	
	 public Token dispatcher(){
		 char readChar;
		 char state = T;
		 
		 try {
			    readChar = (char) inFile.read();
			} catch (IOException e) {
			    e.printStackTrace();
			    return null;
			}
		
		if (readChar == dash){
			if (comment(readChar))
				return null;
		}
		 
		String lex = "";
		
		do {
			state = isValid(readChar, state);
			if ( state != 127)
				lex = lex.concat(Character.toString(readChar));
			else{
				// this is the 
				// fail state
				
				state = T;
				lex ="";
				return null; 
			}
			
			if( state == accept )
				return new Token(lex.substring(0,lex.length() - 1), inFile.getLineNumber() );//remove the last char
			

			try {
			    readChar = (char) inFile.read();
			} catch (IOException e) {
			    e.printStackTrace();
			    return null;
			}
			//col++;
		} while (true);
		
	 }
	 
	 
	 private char isValid(char c, char pre) {

	        if (pre == T && c == T) 
	            return S;
	        if (pre == S && c == S) 
	            return M;
	        if (pre == M && c == M) 
	            return A;
	        if (pre == A && c == A) 
	            return P;
	        if (pre == P && c == P) 
	            return I;
	        if (pre == I && c == I) 
	            return legalMin;
	        if (pre == legalMin && c == openingParen)   //im not sure if I need to care about a colon or opening param
	        	 return accept;
	        if (pre == legalMin && c <= legalMax && c >= legalMin) 
	            return legalMin;
	        
	        return 127; //go back to start state
	}
	
	/*
	 * This idea is to consume the comment
	 * lines
	 */
	private boolean comment(char readChar){
		try {
		    readChar = (char) inFile.read();
		} catch (IOException e) {
		    e.printStackTrace();
		    //return null;
		}
		
		if (readChar == dash){
			
			try {
			    readChar = (char) inFile.read();
			} catch (IOException e) {
			    e.printStackTrace();
			    //return null;
			}
			
			if (readChar != openBracket){
				try {
					inFile.readLine();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}else
			{
				try {
				    readChar = (char) inFile.read();
				} catch (IOException e) {
				    e.printStackTrace();
				    //return null;
				}
				
				if (readChar == openBracket){
					int count = 0;
					while(true){
						try {
						    readChar = (char) inFile.read();
						} catch (IOException e) {
						    e.printStackTrace();
						}
						
						if (readChar == closeBracket)
							count++;
						if (count >=2)
							break;
					}//end while
				}//end if
				
			}//end outer if
			
			return true;
		}//end if
		
		
		
		return false;
	}//end function
	
	
	 public boolean isEOF(){
		boolean result = false;
		
		try {
		    result = inFile.ready();
		} catch (IOException e){
		    System.out.println(e);
		}
		return result;
	}
	

}//end class


